"""
Case Type   : pagehack工具测试
Case Name   : pcr索引类型_pagehack解析结果校验_索引页尾信息_ubtree PCR flag
Create At   : 2025-10-25
Owner       : chen
Description :
    1.建表
    2.创建索引
    3.插入数据
    4.查询索引文件路径
    5.解析
    6.查看解析结果，root页面对应ubtree PCR flag为BTP_ROOT，叶子页面为BTP
Expect      :
    1.成功
    2.成功
    3.成功
    4.成功
    5.成功
    6.成功
History     :
"""

import os
import re
import time
import unittest
from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from yat.test import Node
from yat.test import macro

log = Logger()
primary_sh = CommonSH('PrimaryDbUser')

class Tools_Pagehack_Case0047(unittest.TestCase):
    def setUp(self):
        log.info(f'--------{os.path.basename(__file__)} start--------')
        self.constant = Constant()
        self.pri_node = Node('PrimaryDbUser')
        self.table_name = 't_pagehack_0047'
        self.index_name = 'i_pagehack_0047'

    def test_pagehack(self):
        text = '-------------step1: 建表; expect: 成功-------------'
        log.info(text)
        msg = primary_sh.check_connection_status(self.constant.START_STATUS_MSG)
        self.assertTrue(msg)
        create_table = f'''drop table if exists {self.table_name} cascade;
            create table {self.table_name} (
                id serial primary key,
                name varchar(50),
                description text,
                points point,
                tags text[],
                score double precision,
                created_at timestamp default current_timestamp
            ) with (storage_type=ustore);'''
        res = primary_sh.execut_db_sql(create_table)
        log.info(res)
        self.assertIn(self.constant.CREATE_TABLE_SUCCESS, res)

        text = '-------------step2: 创建索引; expect: 成功-------------'
        log.info(text)
        create_index = f'create index {self.index_name} on ' \
            f'{self.table_name} using ubtree (name) with (index_type=pcr);'
        res = primary_sh.execut_db_sql(create_index)
        log.info(res)
        self.assertIn(self.constant.CREATE_INDEX_SUCCESS, res)

        text = '-------------step3: 插入数据; expect: 成功-------------'
        log.info(text)
        insert_sql = f'''insert into {self.table_name} (name, description, 
            points, tags, score)
            select
                'product_' || n::text,
                'description for product ' || n::text,
                point(random() * 100, random() * 100),
                array[('tag' || (floor(random() * 10)::int)::text), 
                ('category' || (floor(random() * 5)::int)::text)],
                random() * 100
            from generate_series(1, 1000) as n;
        '''
        res = primary_sh.execut_db_sql(insert_sql)
        log.info(res)
        self.assertIn('INSERT 0 1000', res)

        text = '-------------step4: 查询索引文件路径; expect: 成功-------------'
        log.info(text)
        select_sql = f"SELECT pg_relation_filepath('{self.index_name}');"
        res = primary_sh.execut_db_sql(select_sql)
        log.info(res)
        self.assertIn('(1 row)', res)
        index_path = str(res).splitlines()[-2].strip()

        text = '-------------step5: 解析; expect: 成功-------------'
        log.info(text)
        time.sleep(10)
        shell = f'source {macro.DB_ENV_PATH}; ' \
            f'cd {macro.DB_INSTANCE_PATH} && ' \
            f'pagehack -f {index_path} -t ubtree_pcr_index'
        log.info(shell)
        msg = self.pri_node.sh(shell).result()
        log.info(msg)
        self.assertNotIn('ERROR', msg)

        text = '-------------step6: 查看解析结果; expect: 成功-------------'
        log.info(text)
        self.assertIn('ubtree PCR flag: BTP_ROOT', msg)
        self.assertIn('ubtree PCR flag: BTP_LEAF', msg)
        pattern = r'pageCount\s*[:=]?\s*(\d+)'
        match = re.search(pattern, msg)
        self.assertTrue(match)
        pageCount = int(match.group(1))
        pattern = re.compile(r'ubtree PCR flag:\s*' \
            r'(BTP_ROOT|BTP_LEAF|BTP_INTERNAL)', re.IGNORECASE)
        matches = pattern.findall(msg)
        num = len(matches)
        log.info(f'pageCount:{pageCount}')
        log.info(f'BTP_ROOT + BTP_LEAF + BTP_INTERNAL num is: {num}')
        self.assertEqual(num + 1, pageCount)

    def tearDown(self):
        text = '------------------清理环境; expect: 成功------------------'
        log.info(text)
        drop_sql = f'''drop index if exists {self.index_name};
            drop table if exists {self.table_name};'''
        res = primary_sh.execut_db_sql(drop_sql)
        log.info(res)
        self.assertIn(self.constant.DROP_INDEX_SUCCESS_MSG, res)
        self.assertIn(self.constant.DROP_TABLE_SUCCESS, res)